﻿/**********************************************************
 ●项目：Smartkernel
 ●公司：智能核心信息技术研发中心
 ●作者：曹艳白
 ●邮箱：caoyanbai@gmail.com
 ●创建：2008-08-10
**********************************************************/
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Smartkernel.Security.Cryptography
{
    /// <summary>
    /// 智能密码术：提供常用密码安全操作
    /// </summary>
    public static class SmartCryptography
    {
        /// <summary>
        /// 加密方法
        /// </summary>
        /// <param name="input">待加密的字符串</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <returns>加密之后的文本</returns>
        public static string Encrypt(string input, string password)
        {
            return Encrypt(input, password, Encoding.Default);
        }
        /// <summary>
        /// 加密方法
        /// </summary>
        /// <param name="input">待加密的字符串</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>加密之后的文本</returns>
        public static string Encrypt(string input, string password, Encoding encoding)
        {
            //注意iv的长度，必须和key中的密码长度相同
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);
            byte[] datas = encoding.GetBytes(input);
            DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateEncryptor(iv, key), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(datas, 0, datas.Length);
                    cryptoStream.FlushFinalBlock();
                    return Convert.ToBase64String(memoryStream.ToArray());
                }
            }
        }
         /// <summary>
        /// 解密方法
        /// </summary>
        /// <param name="input">待解密的字符串</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <returns>解密之后的文本</returns>
        public static string Decrypt(string input, string password)
        {
            return Decrypt(input, password, Encoding.Default);
        }
        /// <summary>
        /// 解密方法
        /// </summary>
        /// <param name="input">待解密的字符串</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>解密之后的文本</returns>
        public static string Decrypt(string input, string password, Encoding encoding)
        {
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);
            byte[] datas = Convert.FromBase64String(input);
            DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateDecryptor(iv, key), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(datas, 0, datas.Length);
                    cryptoStream.FlushFinalBlock();
                    return encoding.GetString(memoryStream.ToArray());
                }
            }
        }
         /// <summary>
        /// 加密文件的方法
        /// </summary>
        /// <param name="input">待加密的文件路径</param>
        /// <param name="output">加密之后的文件路径</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <returns>加密之后的文本</returns>
        public static void Encrypt(string input, string output, string password)
        {
            Encrypt(input, output, password, Encoding.Default);
        }
        /// <summary>
        /// 加密文件的方法
        /// </summary>
        /// <param name="input">待加密的文件路径</param>
        /// <param name="output">加密之后的文件路径</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>加密之后的文本</returns>
        public static void Encrypt(string input, string output, string password, Encoding encoding)
        {
            //注意iv的长度，必须和key中的密码长度相同
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);
            using (Stream stream = new FileStream(input, FileMode.Open, FileAccess.Read))
            {
                byte[] datas = new byte[stream.Length];
                stream.Read(datas, 0, datas.Length);
                DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateEncryptor(iv, key), CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(datas, 0, datas.Length);
                        cryptoStream.FlushFinalBlock();
                        byte[] buffer = new byte[memoryStream.Length];
                        memoryStream.Position = 0;
                        memoryStream.Read(buffer, 0, buffer.Length);

                        using (Stream newStream = new FileStream(output, FileMode.CreateNew, FileAccess.Write))
                        {
                            newStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 解密文件的方法
        /// </summary>
        /// <param name="input">待解密的文件路径</param>
        /// <param name="output">解密之后保存的路径</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <returns>解密之后的文本</returns>
        public static void Decrypt(string input, string output, string password)
        {
            Decrypt(input, output, password, Encoding.Default);
        }
        /// <summary>
        /// 解密文件的方法
        /// </summary>
        /// <param name="input">待解密的文件路径</param>
        /// <param name="output">解密之后保存的路径</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>解密之后的文本</returns>
        public static void Decrypt(string input, string output, string password, Encoding encoding)
        {
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);
            using (Stream stream = new FileStream(input, FileMode.Open, FileAccess.Read))
            {
                byte[] datas = new byte[stream.Length];
                stream.Read(datas, 0, datas.Length);
                DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateDecryptor(iv, key), CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(datas, 0, datas.Length);
                        cryptoStream.FlushFinalBlock();
                        byte[] buffer = new byte[memoryStream.Length];
                        memoryStream.Position = 0;
                        memoryStream.Read(buffer, 0, buffer.Length);

                        using (Stream newStream = new FileStream(output, FileMode.CreateNew, FileAccess.Write))
                        {
                            newStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                }
            }
        }
         /// <summary>
        /// 加密流的方法
        /// </summary>
        /// <param name="input">待加密的流</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <returns>加密之后的文本</returns>
        public static Stream Encrypt(Stream input, string password)
        {
            return Encrypt(input, password, Encoding.Default);
        }
        /// <summary>
        /// 加密流的方法
        /// </summary>
        /// <param name="input">待加密的流</param>
        /// <param name="password">加密的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>加密之后的文本</returns>
        public static Stream Encrypt(Stream input, string password, Encoding encoding)
        {
            //注意iv的长度，必须和key中的密码长度相同
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);

            byte[] datas = new byte[input.Length];
            input.Read(datas, 0, datas.Length);
            DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
            using (MemoryStream memoryStream = new MemoryStream())
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateEncryptor(iv, key), CryptoStreamMode.Write);
                cryptoStream.Write(datas, 0, datas.Length);
                cryptoStream.FlushFinalBlock();
                memoryStream.Position = 0;
                return memoryStream;
            }
        }
         /// <summary>
        /// 解密流的方法
        /// </summary>
        /// <param name="input">待解密的流</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <returns>解密之后的文本</returns>
        public static Stream Decrypt(Stream input, string password)
        {
            return Decrypt(input, password, Encoding.Default);
        }
        /// <summary>
        /// 解密流的方法
        /// </summary>
        /// <param name="input">待解密的流</param>
        /// <param name="password">加密时用的密码（只能为4～8位长）</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>解密之后的文本</returns>
        public static Stream Decrypt(Stream input, string password, Encoding encoding)
        {
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] key = encoding.GetBytes(password);
            byte[] datas = new byte[input.Length];
            input.Read(datas, 0, datas.Length);
            DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider();
            using (MemoryStream memoryStream = new MemoryStream())
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, desCryptoServiceProvider.CreateDecryptor(iv, key), CryptoStreamMode.Write);
                cryptoStream.Write(datas, 0, datas.Length);
                cryptoStream.FlushFinalBlock();
                memoryStream.Position = 0;
                return memoryStream;
            }
        }
    }
}
